package cn.sherer.utils;

import java.util.List;
import java.util.ArrayList;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import static cn.sherer.utils.StringUtils.isNull;

/**
 * Json工具类
 */
public class JsonUtils {

    // <editor-fold defaultstate="collapsed" desc="转换Json">
    /**
     * 转换Json数组
     * @param object 转换对象
     * @return Json数组
     */
    public static JSONArray toArray(Object object) {
        if (object == null) return new JSONArray();
        try {
            JSONArray result;
            if (object instanceof String) {
                result = JSONArray.parseArray(String.valueOf(object));
            } else if (object instanceof JSONArray) {
                result = (JSONArray) object;
            } else {
                result = JSONArray.parseArray(JSONArray.toJSONString(object));
            }
            return result == null ? new JSONArray() : result;
        } catch (Exception e) {
            return new JSONArray();
        }
    }

    /**
     * 转换Json对象
     * @param object 转换对象
     * @return Json对象
     */
    public static JSONObject toObject(Object object) {
        if (object == null) return new JSONObject();
        try {
            JSONObject result;
            if (object instanceof String) {
                result = JSONObject.parseObject(String.valueOf(object));
            } else if (object instanceof JSONObject) {
                result = (JSONObject) object;
            } else {
                result = JSONObject.parseObject(JSONObject.toJSONString(object));
            }
            return result == null ? new JSONObject() : result;
        } catch (Exception e) {
            return new JSONObject();
        }
    }

    /**
     * 获取子对象
     * @param object 对象
     * @param key 键
     * @return 子对象
     */
    public static Object getObject(Object object, String key) {
        JSONObject jsonObject = toObject(object);
        if (!isNull(key, "").trim().equals("") && jsonObject.containsKey(key)) {
            return jsonObject.get(key);
        } else {
            return null;
        }
    }

    /**
     * 获取子Json对象
     * @param object 对象
     * @param key 键
     * @return 子Json对象
     */
    public static JSONObject getJsonObject(Object object, String key) {
        Object obj = getObject(object, key);
        if (obj != null && obj instanceof JSONObject) {
            return (JSONObject) obj;
        } else {
            return new JSONObject();
        }
    }

    /**
     * 获取子Json数组
     * @param object 对象
     * @param key 键
     * @return 子Json数组
     */
    public static JSONArray getJsonArray(Object object, String key) {
        Object obj = getObject(object, key);
        if (obj != null && obj instanceof JSONArray) {
            return (JSONArray) obj;
        } else {
            return new JSONArray();
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="移除键">
    /**
     * 移除Json对象键
     * @param object Json对象
     * @param keys 移除键
     * @return 移除完Json对象
     */
    public static JSONObject removeObjectKeys(Object object, String... keys) {
        if (object==null) { return new JSONObject(); }
        JSONObject json = toObject(object);
        List<String> list = new ArrayList<>();
        json.keySet().forEach((key) -> { list.add(key); });
        for (String key : keys) {
            if (json.containsKey(key)) {
                json.remove(key);
            }
        }
        return json;
    }

    /**
     * 移除Json数组键
     * @param object Json数组
     * @param keys 移除键
     * @return 移除完Json数组
     */
    public static JSONArray removeArrayKeys(Object object, String... keys) {
        if (object==null) { return new JSONArray(); }
        JSONArray json = toArray(object);
        for (int i = 0; i < json.size(); i++) {
            removeObjectKeys(json.get(i), keys);
        }
        return json;
    }

    /**
     * 移除Json对象的例外键
     * @param object Json对象
     * @param keys 例外键
     * @return 移除完Json对象
     */
    public static JSONObject removeObjectKeysWithout(Object object, String... keys) {
        if (object==null) { return new JSONObject(); }
        JSONObject json = toObject(object);
        List<String> list = new ArrayList<>();
        json.keySet().forEach((key) -> { list.add(key); });
        for (String key : keys) {
            if (list.contains(key)) {
                list.remove(key);
            }
        }
        return removeObjectKeys(object, list.toArray(new String[]{}));
    }

    /**
     * 移除Json数组的例外键
     * @param object Json数组
     * @param keys 例外键
     * @return 移除完Json数组
     */
    public static JSONArray removeArrayKeysWithout(Object object, String... keys) {
        if (object==null) { return new JSONArray(); }
        JSONArray json = toArray(object);
        for (int i = 0; i < json.size(); i++) {
            removeObjectKeysWithout(json.get(i), keys);
        }
        return json;
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="转换">
    /**
     * 转换int数组
     * @param array 转换数组
     * @return int数组
     */
    public static int[] toIntArray(JSONArray array) {
        if (array==null) { return new int[]{}; }
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < array.size(); i++) {
            if (array.get(i) instanceof Integer) {
                list.add(array.getInteger(i));
            } else if (array.get(i) instanceof String && StringUtils.isInteger(array.getString(i))) {
                list.add(Integer.parseInt(array.getString(i)));
            }
        }
        return list.stream().mapToInt(Integer::valueOf).toArray();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="拼接">
    /**
     * 拼接Json数组
     * @param arrays Json数组
     * @return 拼接完Json数组
     */
    public static JSONArray concat(JSONArray... arrays) {
        JSONArray result = new JSONArray();
        for (JSONArray array : arrays) {
            if (array==null) { continue; }
            for (int i = 0; i < array.size(); i++) {
                result.add(array.get(i));
            }
        }
        return result;
    }
    // </editor-fold>

}
